package view;

import domein.Server;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * @author Colin Bundervoet
 * @author Jeroen Pattyn
 * @author Bram Schotte
 * @author Lucas Van Overberghe
 */
public class ServerForm extends javax.swing.JFrame {

    public JScrollPane getjScrollPane1() {
        return jScrollPane1;
    }
    private Server server;
    Thread t;

    /**
     * Creates new form ServerForm
     */
    public ServerForm() {
        initComponents();
        setLocationRelativeTo(null);
    }

    public JList getOnlineUsersList() {
        return this.onlineUsersList;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        portLabel = new javax.swing.JLabel();
        portField = new javax.swing.JTextField();
        startServerButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        serverLogArea = new javax.swing.JTextArea();
        usersLabel = new javax.swing.JLabel();
        serverLogLabel = new javax.swing.JLabel();
        backToMenuButton = new javax.swing.JButton();
        stopServerButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        onlineUsersList = new javax.swing.JList();
        clientButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        portLabel.setText("Port number");

        portField.setText("5000");
        portField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                portFieldActionPerformed(evt);
            }
        });

        startServerButton.setText("Start server");
        startServerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startServerButtonActionPerformed(evt);
            }
        });

        serverLogArea.setEditable(false);
        serverLogArea.setColumns(20);
        serverLogArea.setRows(5);
        jScrollPane1.setViewportView(serverLogArea);

        usersLabel.setFont(new java.awt.Font("Tahoma", 2, 14)); // NOI18N
        usersLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        usersLabel.setText("Connected users");

        serverLogLabel.setFont(new java.awt.Font("Tahoma", 2, 14)); // NOI18N
        serverLogLabel.setText("Server Log");

        backToMenuButton.setText("Menu");
        backToMenuButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                backToMenuButtonActionPerformed(evt);
            }
        });

        stopServerButton.setText("Stop server");
        stopServerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopServerButtonActionPerformed(evt);
            }
        });

        onlineUsersList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                onlineUsersListMousePressed(evt);
            }
        });
        jScrollPane2.setViewportView(onlineUsersList);

        clientButton.setText("Start own client?");
        clientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clientButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 459, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(portLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(portField, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(serverLogLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(19, 19, 19)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(startServerButton, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE)
                            .addComponent(stopServerButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(backToMenuButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(clientButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(63, 63, 63)
                        .addComponent(usersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(portLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(portField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(startServerButton)
                    .addComponent(backToMenuButton))
                .addGap(8, 8, 8)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(serverLogLabel)
                    .addComponent(usersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(stopServerButton)
                    .addComponent(clientButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void portFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_portFieldActionPerformed
    }//GEN-LAST:event_portFieldActionPerformed

    private void startServerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startServerButtonActionPerformed
        String poort = portField.getText();
        if (poort.equals("") || !poort.matches("[0-9]*")) {
            serverLogArea.append("Invalid port number. Please enter a port number.\n");
        } else {
            int port = Integer.parseInt(poort);
            server = new Server(port);
            server.setForm(this);
            t = new Thread() {
                @Override
                public void run() {
                    server.start();
                }
            };
            t.start();
        }
    }//GEN-LAST:event_startServerButtonActionPerformed

    private void backToMenuButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backToMenuButtonActionPerformed
        if (server == null) {
            this.setVisible(false);
            new MenuForm().setVisible(true);
        } else if (!server.isRunning()) {
            this.setVisible(false);
            new MenuForm().setVisible(true);
        } else {
            int choice = JOptionPane.showConfirmDialog(null, "You will be disconnected when you go back to the menu. Continue?", "Exit", JOptionPane.YES_NO_OPTION);

            if (choice == JOptionPane.YES_OPTION) {
                stopServerButtonActionPerformed(evt);
                this.setVisible(false);
                new MenuForm().setVisible(true);
            } else {
            }
        }
    }//GEN-LAST:event_backToMenuButtonActionPerformed

    private void stopServerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopServerButtonActionPerformed
        SimpleDateFormat date = new SimpleDateFormat();
        String time = date.format(new Date());
        if (server == null || !server.isRunning()) {
            getServerLogArea().append(time + ": You have not started the server yet\n");
        } else {
            server.stop();
            t = null;
            server = null;
            getServerLogArea().append(time + ": The server has been stopped\n");
            System.gc();
        }
    }//GEN-LAST:event_stopServerButtonActionPerformed

    private void clientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clientButtonActionPerformed
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new ClientForm();
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }//GEN-LAST:event_clientButtonActionPerformed

    private void onlineUsersListMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_onlineUsersListMousePressed
        JPopupMenu popupMenu = new JPopupMenu();
        popupMenu.add(kickButton = new JMenuItem("kick"));
        popupMenu.add(whoisButton = new JMenuItem("whois"));
        popupMenu.add(opButton = new JMenuItem("Set op"));
        popupMenu.add(deopButton = new JMenuItem("De-op"));
        popupMenu.add(banButton = new JMenuItem("ban"));
        kickButton.addActionListener(new ButtonAction());
        whoisButton.addActionListener(new ButtonAction());
        banButton.addActionListener(new ButtonAction());
        opButton.addActionListener(new ButtonAction());
        deopButton.addActionListener(new ButtonAction());

        if (SwingUtilities.isRightMouseButton(evt) && !onlineUsersList.isSelectionEmpty() && onlineUsersList.locationToIndex(evt.getPoint()) == onlineUsersList.getSelectedIndex()) {
            popupMenu.show(onlineUsersList, evt.getX(), evt.getY());
        }
    }//GEN-LAST:event_onlineUsersListMousePressed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerForm().setVisible(true);
            }
        });
    }

    class ButtonAction implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent evt) {
            if (server == null || !server.isRunning()) {
                SimpleDateFormat date = new SimpleDateFormat();
                String time = date.format(new Date());
                getServerLogArea().append(time + " Server is not connected\n");
            } else {
                if (evt.getSource() == kickButton) {
                    server.showOnLog("kicking " + onlineUsersList.getSelectedValue().toString());
                    server.kick(onlineUsersList.getSelectedValue().toString());
                } else if (evt.getSource() == banButton) {
                    server.showOnLog("banning " + onlineUsersList.getSelectedValue().toString());
                    server.ban(onlineUsersList.getSelectedValue().toString());
                } else if (evt.getSource() == opButton) {
                    server.showOnLog("opping " + onlineUsersList.getSelectedValue().toString());
                    server.op(onlineUsersList.getSelectedValue().toString());
                } else if (evt.getSource() == deopButton) {
                    server.showOnLog("deopping " + onlineUsersList.getSelectedValue().toString());
                    server.deop(onlineUsersList.getSelectedValue().toString());

                } else if (evt.getSource() == whoisButton) {
                    server.showOnLog("whois " + onlineUsersList.getSelectedValue().toString());
                    server.showOnLog(server.whois(onlineUsersList.getSelectedValue().toString()));
                }
            }
        }
    }

    public JTextField getPortField() {
        return portField;
    }

    public JButton getStartServerButton() {
        return startServerButton;
    }

    public void setPortField(JTextField portField) {
        this.portField = portField;
    }

    public JTextArea getServerLogArea() {
        return serverLogArea;
    }

    public void setServerLogArea(JTextArea serverLogArea) {
        this.serverLogArea = serverLogArea;
    }

    public JLabel getServerLogLabel() {
        return serverLogLabel;
    }

    public void setServerLogLabel(JLabel serverLogLabel) {
        this.serverLogLabel = serverLogLabel;
    }
    private JMenuItem kickButton;
    private JMenuItem whoisButton;
    private JMenuItem opButton;
    private JMenuItem deopButton;
    private JMenuItem banButton;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton backToMenuButton;
    private javax.swing.JButton clientButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JList onlineUsersList;
    private javax.swing.JTextField portField;
    private javax.swing.JLabel portLabel;
    private javax.swing.JTextArea serverLogArea;
    private javax.swing.JLabel serverLogLabel;
    private javax.swing.JButton startServerButton;
    private javax.swing.JButton stopServerButton;
    private javax.swing.JLabel usersLabel;
    // End of variables declaration//GEN-END:variables
}
